home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / net / mac / tcpip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-24  |  14.1 KB  |  657 lines

  1. #ifdef _AIX
  2. #include <strings.h>
  3. #endif
  4.  
  5. #ifdef __POWERPC__
  6. #include "GUSI.h"
  7. #endif
  8. #include "tcpip.hpp"
  9. #include <ctype.h>
  10.  
  11. #ifdef __POWERPC__
  12. extern tcpip_protocol tcpip;
  13. #else
  14. tcpip_protocol tcpip;
  15. #endif
  16.  
  17. //#define TCPIP_DEBUG
  18.  
  19. //{{{ net logging stuff
  20. /* 
  21. FILE *log_file=NULL;
  22. extern int net_start();
  23. void net_log(char *st, void *buf, long size)
  24. {
  25.     
  26.   if (!log_file) 
  27.   {
  28.     if (net_start())
  29.       log_file=fopen("client.log","wb");
  30.     else
  31.       log_file=fopen("server.log","wb");
  32.   }
  33.  
  34.  
  35.     fprintf(log_file,"%s%d - ",st,size);
  36.     int i;
  37.     for (i=0;i<size;i++) 
  38.       if (isprint(*((unsigned char *)buf+i)))
  39.         fprintf(log_file,"%c",*((unsigned char *)buf+i));
  40.       else fprintf(log_file,"~");
  41.  
  42.     fprintf(log_file," : ");
  43.  
  44.     for (i=0;i<size;i++) 
  45.     fprintf(log_file,"%02x, ",*((unsigned char *)buf+i),*((unsigned char *)buf+i));
  46.     fprintf(log_file,"\n");
  47.     fflush(log_file);
  48.  
  49. } */
  50. //}}}
  51.  
  52. ////////////////////////////////////////////////////////////////////////
  53. //
  54. //  unix_fd methods
  55. //
  56.  
  57. int unix_fd::read(void *buf, int size, net_address **addr) 
  58. //{{{
  59. {
  60.   int tr=::read(fd,(char*)buf,size);
  61.   if (addr) *addr=NULL;
  62.   return tr;
  63. }
  64. //}}}///////////////////////////////////
  65.  
  66. int unix_fd::write(void *buf, int size, net_address *addr)
  67. //{{{
  68.   if (addr) fprintf(stderr,"Cannot change address for this socket type\n");
  69.   return ::write(fd,(char*)buf,size); 
  70. }
  71. //}}}///////////////////////////////////
  72.  
  73. void unix_fd::broadcastable()
  74. //{{{
  75. {
  76.   int zz;
  77.   if (setsockopt(fd,SOL_SOCKET,SO_BROADCAST,(char *)&zz,sizeof(zz))<0)
  78.   {
  79.     fprintf(stderr,"could not set socket option broadcast");
  80.     return;
  81.   }
  82. }
  83. //}}}///////////////////////////////////
  84.  
  85. ////////////////////////////////////////////////////////////////////////
  86. //
  87. //  tcpip_protocol methods
  88. //
  89.  
  90. net_address *tcpip_protocol::get_local_address()
  91. //{{{
  92. {
  93. #if 0
  94.      struct hostent *l_hn=gethostent();
  95.  
  96.     ip_address *a=new ip_address();
  97.     memset(&a->addr,0,sizeof(a->addr));
  98.     memcpy(&a->addr.sin_addr,*l_hn->h_addr_list,4);  
  99.  
  100.     return a;  
  101. #else
  102.   char my_name[100];                        // check to see if this address is 'hostname'
  103.   gethostname(my_name,100);
  104.   ip_address *ret = 0;
  105.   
  106.   if (my_name[0]<'0' || my_name[0]>'9')
  107.   {
  108.       struct hostent *l_hn=gethostbyname(my_name);
  109.       
  110.       if (l_hn)
  111.       {
  112.           ip_address *a=new ip_address();
  113.           memset(&a->addr,0,sizeof(a->addr));
  114.           memcpy(&a->addr.sin_addr,*l_hn->h_addr_list,4);  
  115.     
  116.           return a;
  117.       }
  118.       else
  119.       {
  120.           printf("Enter ip address:");
  121.           gets(my_name);
  122.       }
  123.     }  
  124.  
  125.   char tmp[4],*np;
  126.     sockaddr_in host;
  127.   
  128.   np = my_name;
  129.   for (int i=0; i<4; i++)
  130.   {
  131.     int num = 0;
  132.     while (*np)
  133.     {
  134.       if (*np=='.')
  135.       {
  136.         np++;
  137.         break;
  138.       }
  139.       num = num*10 + *np - '0';
  140.       np++;
  141.     }
  142.     tmp[i] = num;
  143.   }
  144.   
  145.   memset( (char*) &host,0, sizeof(host));
  146.   host.sin_family = AF_INET;
  147.   host.sin_addr.s_addr = htonl(INADDR_ANY);
  148.   memcpy(&host.sin_addr,tmp,sizeof(in_addr));
  149.   
  150.     return new ip_address(&host);
  151. #endif
  152. }
  153. //}}}///////////////////////////////////
  154.  
  155. net_address *tcpip_protocol::get_node_address(char *&server_name, 
  156.                                                                                             int def_port, int force_port)
  157. //{{{
  158. {
  159.   sockaddr_in host;
  160.  
  161.     if (server_name[0]>='0' && server_name[0]<='9')
  162.     {
  163.       char tmp[4],*np;
  164.       
  165.       np = server_name;
  166.       for (int i=0; i<4; i++)
  167.       {
  168.         int num = 0;
  169.         while (*np && *np!=':')
  170.         {
  171.           if (*np=='.')
  172.           {
  173.             np++;
  174.             break;
  175.           }
  176.           num = num*10 + *np - '0';
  177.           np++;
  178.         }
  179.         tmp[i] = num;
  180.         if (*np == ':' & !force_port)
  181.         {
  182.             int x;
  183.           if (sscanf(np+1,"%d",&x)==1)
  184.               def_port=x;
  185.           }
  186.       }
  187.       
  188.       memset( (char*) &host,0, sizeof(host));
  189.       host.sin_family = AF_INET;
  190.       host.sin_port = htons(def_port);
  191.       host.sin_addr.s_addr = htonl(INADDR_ANY);
  192.       memcpy(&host.sin_addr,tmp,sizeof(in_addr));
  193.       
  194.       return new ip_address(&host);
  195.     }
  196.     else
  197.     {
  198.       char name[256],*np;
  199.  
  200.       np=name;
  201.       while (*server_name && *server_name!=':' && *server_name!='/')
  202.         *(np++)=*(server_name)++;
  203.       *np=0;
  204.       if (*server_name==':')
  205.       {
  206.         server_name++;
  207.         char port[256],*p;
  208.         p=port;
  209.         while (*server_name && *server_name!='/')
  210.           *(p++)=*(server_name++);
  211.         *p=0;
  212.         int x;
  213.         if (!force_port)
  214.         {
  215.           if (sscanf(port,"%d",&x)==1) def_port=x;
  216.           else return 0;
  217.         }
  218.       }
  219.     
  220.       if (*server_name=='/') server_name++;
  221.     
  222.       hostent *hp=gethostbyname(name);
  223.       if (!hp)
  224.       { 
  225.         fprintf(stderr,"unable to locate server named '%s'\n",name);
  226.         return 0;
  227.       }
  228.       
  229.       memset( (char*) &host,0, sizeof(host));
  230.       host.sin_family = AF_INET;
  231.       host.sin_port = htons(def_port);
  232.       host.sin_addr.s_addr = htonl(INADDR_ANY);
  233.       memcpy(&host.sin_addr,hp->h_addr,hp->h_length);
  234.     }
  235.   return new ip_address(&host);
  236. }
  237. //}}}///////////////////////////////////
  238.  
  239. net_socket *tcpip_protocol::connect_to_server(net_address *addr, net_socket::socket_type sock_type)
  240. //{{{
  241. {
  242.   if (addr->protocol_type()!=net_address::IP)
  243.   {
  244.     fprintf(stderr,"Procotol type not supported in the executable\n");
  245.     return NULL;
  246.   }
  247.  
  248.   int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
  249.   if (socket_fd<0) 
  250.   {
  251.     fprintf(stderr,"unable to create socket (too many open files?)\n");
  252.     return 0;
  253.   }
  254.  
  255. #ifndef __POWERPC__
  256.   int zz;
  257.   if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  258.   {
  259.     fprintf(stderr,"could not set socket option reuseaddr");
  260.     return 0;
  261.   }
  262. #endif
  263.     
  264.   if (connect(socket_fd, (struct sockaddr *) &((ip_address *)addr)->addr, sizeof( ((ip_address *)addr)->addr ))==-1)
  265.   { 
  266.     fprintf(stderr,"unable to connect\n");
  267.     close(socket_fd);
  268.     return 0;
  269.   }
  270.  
  271.   if (sock_type==net_socket::SOCKET_SECURE)
  272.     return new tcp_socket(socket_fd);
  273.   else
  274.     return new udp_socket(socket_fd);
  275. }
  276. //}}}///////////////////////////////////
  277.  
  278. net_socket *tcpip_protocol::create_listen_socket(int port, net_socket::socket_type sock_type)
  279. //{{{
  280. {
  281.   int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
  282.   if (socket_fd<0) 
  283.   {
  284.     fprintf(stderr,"unable to create socket (too many open files?)\n");
  285.     return 0;
  286.   }
  287.  
  288. #ifndef __POWERPC__
  289.   int zz;
  290.   if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  291.   {
  292.     fprintf(stderr,"could not set socket option reuseaddr");
  293.     return 0;
  294.   }
  295. #endif
  296.  
  297.   net_socket *s;
  298.   if (sock_type==net_socket::SOCKET_SECURE)
  299.     s=new tcp_socket(socket_fd);
  300.   else s=new udp_socket(socket_fd);
  301.   if (s->listen(port)==0)
  302.   {   
  303.     delete s;
  304.     return 0;
  305.   }
  306.  
  307.   return s;
  308. }
  309. //}}}///////////////////////////////////
  310.  
  311. net_socket *tcpip_protocol::start_notify(int port, void *data, int len)
  312. //{{{
  313. {
  314.     if (responder)
  315.     {
  316.         delete responder;
  317.         delete bcast;
  318.         responder = 0;
  319.     }
  320.     
  321.     int resp_len = strlen(notify_response);
  322.   notify_len = len + resp_len + 1;
  323.   strcpy(notify_data,notify_response);
  324.     notify_data[resp_len] = '.';
  325.   memcpy(notify_data+resp_len+1,data,len);
  326.   
  327.   // create notifier socket
  328. #ifdef TCPIP_DEBUG
  329.     fprintf(stderr,"Creating notifier on port %d\n",port);
  330. #endif
  331.   notifier = create_listen_socket(port, net_socket::SOCKET_FAST);
  332.   
  333.   if (notifier)
  334.   {
  335.     notifier->read_selectable();
  336.     notifier->write_unselectable();
  337.   }
  338.   else
  339.         fprintf(stderr,"Couldn't start notifier\n");
  340.   
  341.   return notifier;
  342. }
  343. //}}}///////////////////////////////////
  344.  
  345. void tcpip_protocol::end_notify()
  346. //{{{
  347. {
  348.   if (notifier)
  349.     delete notifier;
  350.   notifier = 0;
  351.  
  352.   notify_len = 0;
  353. }
  354. //}}}///////////////////////////////////
  355.  
  356. int tcpip_protocol::handle_notification()
  357. //{{{
  358. {
  359.   if (!notifier)
  360.     return 0;
  361.     
  362.   if (notifier->ready_to_read())
  363.   {
  364.     char buf[513];
  365.     int len;
  366.     // got a notification request "broadcast"
  367.     ip_address *addr;
  368.  
  369. #ifdef TCPIP_DEBUG
  370.         printf("Notifier: ");
  371. #endif
  372.  
  373.     len = notifier->read(buf, 512, (net_address**)&addr);
  374. #ifdef TCPIP_DEBUG
  375.         if (len>0) {
  376.             buf[len] = 0;
  377.             printf("[%s] ",buf);
  378.         }
  379. #endif
  380.     if (addr && len>0)
  381.     {
  382.             buf[len] = 0;
  383.       if  (strcmp(buf, notify_signature)==0) {
  384.                 char s[256];
  385. #ifdef TCPIP_DEBUG
  386.                 addr->store_string(s,256);
  387.                 printf("responding to %s",s);
  388. #endif
  389.         // send notification data to requester
  390.         notifier->write(notify_data,notify_len,addr);
  391.             }
  392.         
  393.       delete addr;
  394.     }
  395. #ifdef TCPIP_DEBUG
  396.         printf("\n");
  397. #endif
  398.     return 1;
  399.   }
  400.   if (notifier->error())
  401.   {
  402.     fprintf(stderr,"Error on notification socket!\n");
  403.     return 1;
  404.   }
  405.  
  406.   return 0;
  407. }
  408. //}}}///////////////////////////////////
  409.  
  410. net_address *tcpip_protocol::find_address(int port, char *name)
  411. //{{{
  412. {
  413.   // name should be a 256 byte buffer
  414.     char s[256];
  415.  
  416.     end_notify();
  417.  
  418.   if (!responder) {
  419. //#ifdef TCPIP_DEBUG
  420.         fprintf(stderr,"Creating responder on port %d\n",port);
  421. //#endif
  422.     responder = create_listen_socket(port, net_socket::SOCKET_FAST);
  423.         responder->read_selectable();
  424.         responder->write_unselectable();
  425.     bcast = (ip_address *)get_local_address();
  426.     bcast->set_port(port);
  427.     
  428. //#ifdef TCPIP_DEBUG
  429.         *((unsigned char *)(&bcast->addr.sin_addr)+3) = 255;
  430.         bcast->store_string(s,256);
  431.         fprintf(stderr,"Simulating broadcast to [%s]\n",s);
  432. //#endif
  433.  
  434.         *((unsigned char *)(&bcast->addr.sin_addr)+3) = 0;        
  435.     }
  436.  
  437.   if (responder)
  438.   {
  439.     int i;
  440.     
  441.     for (i=0; i<5; i++)
  442.     {
  443. #ifdef TCPIP_DEBUG
  444.             bcast->store_string(s,256);
  445.             fprintf(stderr,"\r[%s]",s);
  446. #endif
  447.         int found = 0;
  448.         
  449.         for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
  450.             if ( *((*p)->addr) == *bcast )
  451.                 found = 1;
  452.         for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
  453.             if ( *((*q)->addr) == *bcast )
  454.                 found = 1;
  455.                 
  456.             if (!found) {
  457.                 responder->write((void*)notify_signature,
  458.                                                  strlen(notify_signature),bcast);
  459.                 select(0);
  460.             }
  461.         *((unsigned char *)(&bcast->addr.sin_addr)+3) += 1;
  462.     
  463.         select(0);
  464.         
  465.         if (!servers.empty())
  466.             break;
  467.         }
  468.   }
  469.   
  470.   if (servers.empty())
  471.     return 0;
  472.  
  473.   servers.move_next(servers.begin_prev(), returned.begin_prev());
  474.     ip_address *ret = (ip_address*)(*returned.begin())->addr->copy();
  475.     strcpy(name,(*returned.begin())->name);
  476.  
  477. #ifdef TCPIP_DEBUG
  478.     ret->store_string(s,256);
  479.     fprintf(stderr,"Found [%s]\n",s);
  480. #endif
  481.  
  482.   return ret;
  483. }
  484. //}}}///////////////////////////////////
  485.  
  486. void tcpip_protocol::reset_find_list()
  487. //{{{
  488. {
  489.     p_request p;
  490.     
  491.     for (p=servers.begin(); p!=servers.end(); ++p)
  492.         delete (*p)->addr;
  493.     for (p=returned.begin(); p!=returned.end(); ++p)
  494.         delete (*p)->addr;
  495.         
  496.   servers.erase_all();
  497.   returned.erase_all();
  498. }
  499. //}}}///////////////////////////////////
  500.  
  501. int tcpip_protocol::handle_responder()
  502. //{{{
  503. {
  504.   if (!responder)
  505.     return 0;
  506.     
  507.   if (responder->ready_to_read())
  508.   {
  509.     char buf[513];
  510.     int len;
  511.     // got a notification response
  512.     ip_address *addr;
  513.  
  514. #ifdef TCPIP_DEBUG
  515.         fprintf(stderr,"Responder: ");
  516. #endif
  517.  
  518.     len = responder->read(buf, 512, (net_address**)&addr);
  519.  
  520. #ifdef TCPIP_DEBUG
  521.         if (len>0) {
  522.             buf[len] = 0;
  523.             fprintf(stderr,"[%s] ",buf);
  524.         }
  525. #endif
  526.     if (addr && len>0)
  527.     {
  528.         buf[len] = 0;
  529.       buf[4] = 0;                                                // ack! hard coded numbers for now
  530.       if (strcmp(buf,notify_response)==0)
  531.       {
  532.           int found=0;
  533.           for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
  534.               if ( *((*p)->addr) == *addr)
  535.                    found = 1;
  536.             for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
  537.                 if ( *((*q)->addr) == *addr )
  538.                     found = 1;
  539.                    
  540.           if (!found)
  541.           {
  542.                     char s[256];
  543.                     RequestItem *r = new RequestItem;
  544.                     r->addr = addr;
  545.                     strcpy(r->name,buf+5);                    // ack hard coded numbers for now
  546.             servers.insert(r);
  547. #ifdef TCPIP_DEBUG
  548.                     addr->store_string(s,256);
  549.                     fprintf(stderr,"accepted %s",s);
  550. #endif
  551.                 }
  552.             }
  553.       else {
  554.         delete addr;
  555.             }
  556.     }
  557. #ifdef TCPIP_DEBUG
  558.     fprintf(stderr,"\n");
  559. #endif
  560.  
  561.     return 1;
  562.   }
  563.   if (responder->error())
  564.   {
  565.     fprintf(stderr,"Error on responder socket!\n");
  566.     return 1;
  567.   }
  568.  
  569.   return 0;
  570. }
  571. //}}}///////////////////////////////////
  572.  
  573. tcpip_protocol::tcpip_protocol()
  574. //{{{
  575.   : notifier(0), notify_len(0), responder(0)
  576. {
  577. #ifdef __POWERPC__
  578.   GUSISetup(GUSIwithSIOUXSockets);
  579.   GUSISetup(GUSIwithPPCSockets);
  580. #endif  
  581.   FD_ZERO(&master_set);  
  582.   FD_ZERO(&master_write_set);  
  583.   FD_ZERO(&read_set);
  584.   FD_ZERO(&exception_set);
  585.   FD_ZERO(&write_set);
  586. }
  587. //}}}///////////////////////////////////
  588.  
  589. int tcpip_protocol::select(int block)
  590. //{{{
  591. {
  592.   int ret;
  593.   
  594.   memcpy(&read_set,&master_set,sizeof(master_set));
  595.   memcpy(&exception_set,&master_set,sizeof(master_set));
  596.   memcpy(&write_set,&master_write_set,sizeof(master_set));
  597.   if (block)
  598.   {
  599.     ret = 0;
  600.     while (ret == 0) {
  601.       // get number of sockets ready from system call
  602.       ret = ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,NULL);
  603.  
  604.       // remove notifier & responder events from the count of sockets selected
  605.       if (handle_notification())
  606.         ret--;
  607.       if (handle_responder())
  608.         ret--;
  609.     }
  610.   }
  611.   else
  612.   {
  613.     timeval tv={0,0};
  614.     // get number of sockets ready from system call
  615.     ret = ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,&tv);
  616.  
  617.     // remove notifier & responder events from the count of sockets selected
  618.     if (handle_notification())
  619.       ret--;
  620.     if (handle_responder())
  621.       ret--;
  622.   }
  623.   return ret;
  624. }
  625. //}}}///////////////////////////////////
  626.  
  627. void tcpip_protocol::cleanup()
  628. //{{{
  629. {
  630.     if (notifier)
  631.         end_notify();
  632.         
  633.     reset_find_list();
  634.         
  635.     if (responder) {
  636.         delete responder;
  637.         delete bcast;
  638.         responder = 0;
  639.     }
  640. }
  641. //}}}///////////////////////////////////
  642.  
  643. //{{{ Revision Log
  644. /*//////////////////////////////////////////////////////////////////////
  645. $Log$
  646. //////////////////////////////////////////////////////////////////////
  647. */
  648. //}}}
  649.  
  650. //{{{ Emacs Locals
  651. // Local Variables:
  652. // folded-file: t
  653. // End:
  654. //}}}
  655.  
  656.